const name = '';
//引入node模块，一会操作文件，输入，生成，输出都是需要这个路径
const path = require('path');
const timestamp = new Date().getTime();
const { defineConfig } = require('@vue/cli-service');
const { compileTemplate } = require('@vue/compiler-dom');
//css剥离到独立文件
//引入gzip压缩插件
const CompressionPlugin = require('compression-webpack-plugin');
const packageName = require('./package.json').name;
//自动导入全局插件
const unpluginAutoImport = require('unplugin-auto-import/webpack');
const Components = require('unplugin-vue-components/webpack');
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
//开发环境动态设置反向代理url，不需要重新启动
const getActiveProxy = require('./proxy-url');
let compressionPluginEntity = [];
let argv = process.argv;
let isLibPackage = false;
if (argv.indexOf('--lib') >= 0 || process.env.VUE_APP_CURRENTMODE === 'sdk') {
  isLibPackage = true;
}
// add by xiaomw 2024/1/24 是否发布lib包
const libVersion = process.env.LIB_VERSION || '';
// add by xiaomw 2024/1/23 获取多页配置模块
const pageConfig = require('./pages');
if (!isLibPackage) {
  // gzip压缩配置
  compressionPluginEntity = [
    new CompressionPlugin({
      //此插件不能使用太高的版本，否则报错：TypeError: Cannot read property 'tapPromise' of undefined
      // filename: "[path][base].gz", // 这种方式是默认的，多个文件压缩就有多个.gz文件，建议使用下方的写法
      // filename: '[path].gz[query]', //  使得多个.gz文件合并成一个文件，这种方式压缩后的文件少，建议使用
      algorithm: 'gzip', // 官方默认压缩算法也是gzip
      test: /\.js$|\.html$|\.css$/, // 使用正则给匹配到的文件做压缩，这里是给html、css、js以及字体（.ttf和.woff和.eot）做压缩
      threshold: 10240, //以字节为单位压缩超过此大小的文件，使用默认值10240吧
      minRatio: 0.8, // 最小压缩比率，官方默认0.8
      //是否删除原有静态资源文件，即只保留压缩后的.gz文件，建议这个置为false，还保留源文件。以防：
      // 假如出现访问.gz文件访问不到的时候，还可以访问源文件双重保障
      deleteOriginalAssets: false,
      exclude: /config/
    })
  ];
}

/***********************add by xiaomw  2024/1/23  读取并解析多页配置********************************************************/
// 生成多页面配置
const pageList = pageConfig.pageList;
// 多页面分片的配置
const splitChunksCacheGroupsOptions = pageConfig.splitChunksCacheGroupsOptions;
// 多页面配置对象
let pages = {};
// 当前页和剥离该页的chunk配置
let pagesFileBack = {};
for (let pageItem of pageList) {
  pages[pageItem.item.name] = pageItem.item;
  pagesFileBack[pageItem.item.name] = pageItem.fileBlacklist;
}
// 解析分片配置
let splitChunksCacheGroups = {
  default: false
};
for (let cacheGroupsItme of splitChunksCacheGroupsOptions) {
  splitChunksCacheGroups[cacheGroupsItme.chunkTitle] = {
    name: cacheGroupsItme.name,
    priority: cacheGroupsItme.priority,
    reuseExistingChunk: true
  };
  if (cacheGroupsItme.test.isRegExp) {
    let regexString = cacheGroupsItme.test.urlOrRegExp;
    // 去除正则字面量外的斜杠和反斜线
    const regexPattern = regexString.slice(1, -1).replace(/\\/g, '\\\\');

    // 使用RegExp构造函数创建正则表达式对象
    splitChunksCacheGroups[cacheGroupsItme.chunkTitle].test = new RegExp(regexPattern);
  } else {
    splitChunksCacheGroups[cacheGroupsItme.chunkTitle].test = resolve(`./${cacheGroupsItme.test.urlOrRegExp}`);
  }
}
module.exports = defineConfig({
  // 资源是否需要进行转义
  transpileDependencies: [],

  // 配置部署应用包时的基本 URL
  publicPath: process.env.NODE_ENV === 'development' ? '/' : './',

  // 配置输出文件的目录
  outputDir: process.env.outputDir,

  // 配置静态资源的目录
  assetsDir: 'static',

  // 是否使用 eslint-loader 在开发过程中校验代码
  lintOnSave: process.env.NODE_ENV !== 'production',

  //多页面入口配置
  pages: pages,

  // 配置 Webpack 的相关选项
  configureWebpack: {
    name: name,
    externals: {
      vue: 'Vue'
    },
    plugins: [
      ...compressionPluginEntity,
      unpluginAutoImport.default({
        imports: ['vue', 'vue-router'],
        eslintrc: {
          enabled: true,
          filepath: './.eslintrc-auto-import.json'
        }
      }),
      // 组件按需自动注册
      Components({
        resolvers: [ElementPlusResolver()]
      })
    ],
    // 自定义 Webpack 配置
    output: {
      filename: `[name].${timestamp}${libVersion}.js`,
      chunkFilename: `[name].${timestamp}${libVersion}.js`,
      library: `${packageName}-[name]`,
      libraryTarget: 'umd',
      chunkLoadingGlobal: `webpackJsonp_${packageName}`
    }
  },
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        options.compiler = compileTemplate; // 将 compileTemplate 函数赋值给编译器选项
        return options;
      });
    config.module.rule('svg').exclude.add(resolve('src/form-designer/icons')).end();
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/form-designer/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end();
    // 配置url-loader处理字体文件
    config.module
      .rule('fonts')
      .test(/\.(ttf|otf|eot|woff|woff2)$/)
      .use('url-loader')
      .loader('url-loader')
      .tap(options => {
        return options;
      });
    /* 为nanoid设置别名  
      在Vue 3中，nanoid默认使用了非安全的随机算法，而webpack默认会使用安全的随机算法。
      通过将别名设置为nanoid/non-secure，我们可以告诉webpack使用非安全的随机算法来解决这个问题
    */
    config.resolve.alias.set('nanoid', 'nanoid/non-secure');

    //add by xiaomw 如果是生产环境则使用webpack提供的分包工具来对静态资源进行分包。也有利于对于引用第三方文件进行静态缓存。
    config.optimization.splitChunks({
      minSize: 30000, //默认为30000 形成一个新代码块最小体积
      minChunks: 1, //默认为1 在分割前，这个代码默认被引用次数
      chunks: 'all',
      cacheGroups: splitChunksCacheGroups
    });
  },
  // 配置开发服务器的行为
  devServer: {
    open: true,
    host: '0.0.0.0',
    hot: true,
    port: 8087,
    https: false,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': '*',
      'Access-Control-Allow-Methods': '*'
    },
    proxy: {
      '/rest': {
        target: 'http://192.168.102.91:8083/rest', //API服务器的地址。该行请勿修改或者删除，要配其他ip请注释该行，选用下面的ip地址/
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/rest': ''
        },
        router: () => {
          return getActiveProxy('rest');
        },
        onProxyRes: function (proxyRes, req) {
          if (req.method === 'OPTIONS') {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Allow-Methods'] = 'GET,POST,OPTIONS,PUT,DELETE,FETCH';
            // 这里的参数，根据自己项目增删
            proxyRes.headers['Access-Control-Allow-Headers'] =
              'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,userid,w3auth,requestbybrowser,tyinjectparams';
            proxyRes.statusCode = 204;
          } else {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Expose-Headers'] = '*';
          }
        }
      },
      '/typrjmng': {
        target: 'http://192.168.102.91:9588', //API服务器的地址。该行请勿修改或者删除，要配其他ip请注释该行，选用下面的ip地址
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/typrjmng': ''
        },
        router: () => {
          return getActiveProxy('typrjmng');
        },
        onProxyRes: function (proxyRes, req) {
          if (req.method === 'OPTIONS') {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Allow-Methods'] = 'GET,POST,OPTIONS,PUT,DELETE,FETCH';
            // 这里的参数，根据自己项目增删
            proxyRes.headers['Access-Control-Allow-Headers'] =
              'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,userid,w3auth,requestbybrowser,tyinjectparams';
            proxyRes.statusCode = 204;
          } else {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Expose-Headers'] = '*';
          }
        }
      },
      '/mock': {
        target: 'http://192.168.102.91:8887/mock',
        changeOrigin: true,
        pathRewrite: {
          '^/mock': ''
        },
        router: () => {
          return getActiveProxy('mock');
        }
      }
    }
  }
});

function resolve(dir) {
  return path.join(__dirname, dir);
}
